import 'dart:core';

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import '../common/flatPanel.dart';
import '../models/changeLogItem.dart';
import '../parts/changeLogDialog.dart';
import '../utils/dataSource.dart';
import '../utils/screw.dart';

mixin ChangeLogController {
  final mDb = DataSource();

  String mTable;
  int placeHolder = -1;
  var mViewState = ViewState.Initial;
  String mEntry;
  var mEntries = <String>[];
  var mItems = <ChangeLogItem>[];
  ChangeLogItem mItem;

  void onConnectDB();

  void onUpdateTopics();

  void onUpdateView();

  void onAddItem();

  void onEditItem();

  void onDeleteItem();

  void onTapItem();

  Future<void> disposeAction() async {
    mEntries.clear();
    mItems.clear();
    await mDb.close();
  }

  Future<void> connectDbAction(
      BuildContext context, String entry, Function function) async {
    bool result = await mDb.connectFromHive(entry);
    if (result) {
      function();
    } else {
      Screw.showToast(context, '无法连接到数据库!');
    }
  }

  Future<void> addItemAction(BuildContext context) async {
    var inputItem = ChangeLogItem();
    if (mEntry != null && mEntry.isNotEmpty) inputItem.entry = mEntry;

    var item = await showChangeLogDialog(context, item: inputItem);
    if (item == null) return;

    if (mDb.isConnect) {
      var result = await mDb.query(
          'insert into $mTable (entry,date_,version,detail) values (?,?,?,?)',
          [item.entry, item.date, item.version, item.detail]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> editItemAction(BuildContext context) async {
    if (mItem?.id == 0) return;

    var item = await showChangeLogDialog(context, item: mItem);
    if (item == null || mItem.isEqual(item)) return;

    if (mDb.isConnect) {
      var result = await mDb.query(
          'update $mTable set entry=?,date_=?,version=?,detail=? where id=?',
          [item.entry, item.date, item.version, item.detail, item.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> deleteItemAction() async {
    if (mItem?.id == 0) return;

    if (mDb.isConnect) {
      var result =
          await mDb.query('delete from $mTable where id=?', [mItem.id]);
      if (result.affectedRows == 1) onUpdateView();
    }
  }

  Future<void> updateTopics() async {
    if (mEntries.isNotEmpty) mEntries.clear();

    if (mDb.isConnect) {
      var items = <String>[];
      var results = await mDb.query('select entry from $mTable group by entry');
      results.forEach((element) {
        items.add(element[0] ?? '');
      });
      mEntries = items;
    }
  }

  Future<void> updateViewAction() async {
    if (mEntry.isEmpty) return;

    if (mDb.isConnect) {
      var items = <ChangeLogItem>[];
      var results = await mDb.query(
          'select id,date_,version,detail from $mTable where entry=?',
          [mEntry]);
      results.forEach((element) {
        var item = ChangeLogItem(
            id: element[0],
            entry: mEntry,
            date: element[1] ?? '',
            version: element[2] ?? '',
            detail: element[3] ?? '');
        items.add(item);
      });
      mItems = items;
    }
  }

  Widget genTopicViewAction({TextStyle style}) {
    return ListView.builder(
        itemCount: mEntries.length,
        itemBuilder: (c, index) {
          return ListTile(
              leading: Icon(Icons.label_important),
              title: Text(mEntries[index], style: style),
              onTap: () {
                mEntry = mEntries[index];
                onUpdateView();
              });
        });
  }

  Widget genListViewAction({TextStyle style}) {
    return ListView.separated(
      itemCount: mItems.length,
      itemBuilder: (context, index) {
        return ListTile(
          leading: Icon(placeHolder == mItems[index].id
              ? Icons.radio_button_checked
              : Icons.radio_button_unchecked),
          title: Text(mItems[index].date, style: style),
          subtitle: Text(mItems[index].version + ' ,' + mItems[index].detail),
        );
      },
      separatorBuilder: (context, i) => Divider(),
    );
  }

  Widget genFloatingActionButtonAction() {
    switch (mViewState) {
      case ViewState.Initial:
        return FloatingActionButton(
          child: FaIcon(FontAwesomeIcons.plug),
          onPressed: onConnectDB,
        );
      case ViewState.CheckedView:
        return FloatingActionButton(
          child: Icon(Icons.edit),
          onPressed: onEditItem,
        );
      default:
        return FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: onAddItem,
        );
    }
  }

  Future<void> _showDeleteConfirmDialog(BuildContext context) async {
    showDialog(
        context: context,
        builder: (context) {
          return AlertDialog(
            title: Text('操作确认'),
            content: Text('确定要删除吗？ 不可恢复！'),
            actions: <Widget>[
              FlatButton(
                child: Text('取消'),
                onPressed: () => Navigator.of(context).pop(),
              ),
              FlatButton(
                child: Text('确定'),
                onPressed: () {
                  onDeleteItem();
                  Navigator.of(context).pop();
                },
              ),
            ],
          );
        });
  }

  PopupMenuButton<String> genPopupMenuButtonAction(BuildContext context) {
    return PopupMenuButton<String>(
      offset: Offset(0, 60),
      itemBuilder: (context) {
        return <PopupMenuEntry<String>>[
          PopupMenuItem<String>(
            value: 'updateTopics',
            child: Text('更新列表'),
          ),
          PopupMenuItem<String>(
            value: 'updateView',
            child: Text('更新视图'),
          ),
          PopupMenuDivider(),
          PopupMenuItem<String>(
            value: 'deleteItem',
            child: Text('删除...'),
          ),
        ];
      },
      onSelected: (value) {
        if (value == 'updateTopics')
          onUpdateTopics();
        else if (value == 'updateView')
          onUpdateView();
        else if (value == 'deleteItem') _showDeleteConfirmDialog(context);
      },
    );
  }
}
